/*
 * Copyright (c) 2011 Vasile Vilvoiu. All rights reserved.
 *   
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * cmgr.h - layer over the sockets API that standardizes connections
 */
#pragma once

#include "thread.h"

/* windows stuff here */
#if defined _WIN32 || defined _WIN64

#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2def.h>

typedef WSADATA CMGR_SOCKETS_INIT;
typedef SOCKET CMGR_SOCKET;
#define CMGR_NULL_SOCKET INVALID_SOCKET

#endif

/* linux stuff here */
#ifdef __linux__
#error Code not ported yet.
#endif

/* cross platform code here */
#define MAX_PORT	65535

typedef int CMGR_PORT;

typedef enum cmgr_connection_state CMGR_CONNECTION_STATE;
enum cmgr_connection_state {
	ST_READY = 0,
	ST_OPEN,
	ST_CLOSED
};

typedef enum cmgr_connection_type CMGR_CONNECTION_TYPE;
enum cmgr_connection_type {
	CONN_UNKNOWN = 0,		/* ununitialized */
	CONN_LISTENER,			/* listener connection */
	CONN_CLIENT,			/* client connection spawned by listener */
	CONN_OUTGOING			/* outgoing connection */
};

typedef struct cmgr_connection CMGR_CONNECTION;
struct cmgr_connection {
	CMGR_CONNECTION_STATE status;
	CMGR_CONNECTION_TYPE type;
	CMGR_PORT port;
	CMGR_SOCKET socket;

	THREAD_ENTRY entry;
	THREAD_HANDLE thread;
};

extern int cmgr_init();
extern int cmgr_kill();

extern int cmgr_create_listener(int port, THREAD_ENTRY entry, CMGR_CONNECTION **listener);

extern int cmgr_register_connection(CMGR_CONNECTION *connection);
extern int cmgr_handle_connections();